#pragma once

#include "../DefinesCore.hpp"
#ifdef CYBERTRON_WIN
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/times.h> // clock_t
#endif
#include "cybertron/core/UtilProcess.hpp"

#include <cstring> // for memset
#include <string>
#include <vector>

// example: CybertronCoreTest/TestUtilSysRes.cpp

CYBERTRON_BEGIN

struct proc_stat_t
{
	proc_stat_t() { std::memset(this, 0, sizeof(proc_stat_t));}
	proc_stat_t(ProcessHandle ph) {
		std::memset(this, 0, sizeof(proc_stat_t));
		setHandle(ph);
	}
	void setHandle(ProcessHandle ph) {
#ifdef CYBERTRON_WIN
		handle = ph.mHandle;
#else 
		pid = ph.mHandle;
#endif
	}
#ifdef CYBERTRON_WIN
	proc_stat_t(HANDLE h) { 
		std::memset(this, 0, sizeof(proc_stat_t)); 
		handle = h;
	}
	HANDLE handle;
	int64_t last_time_;
	int64_t last_system_time_;
#else
	proc_stat_t(pid_t p) {
		std::memset(this, 0, sizeof(proc_stat_t));
		pid = p;
	}

	pid_t pid;
	clock_t  ticks;
	unsigned long utime;
	unsigned long stime;
	long cutime;
	long cstime;
	unsigned long vsize; // virtual memory size in bytes
	unsigned long rss; //Resident  Set  Size in bytes
#endif
};

class UtilSysRes
{
public:
	// coreCount the number of cores
	CybertronCoreAPI static uint32_t coreCount();
	// procNames the name of processes
	CybertronCoreAPI static std::vector<std::string> procNames();
	// sysCpuUsage total cpu usage

	// total cpu usage. persent  
	// if the return value is negative, check errno\getlasterror
	CybertronCoreAPI static int32_t sysCpuUsage();
	// sysMemUsage total memory usage. persent
	// if the return value is negative, check errno\getlasterror
	CybertronCoreAPI static int32_t sysMemUsage();
	// sysMemory current total physical memory, in MB
	// if the return value is negative, check errno\getlasterror
	CybertronCoreAPI static int32_t sysMemory();
	
	// sysCpuUsage single process's cpu usage. persent
	// if the return value is negative, check errno\getlasterror
	CybertronCoreAPI static int32_t procCpuUsage(proc_stat_t* proc);
	// sysMemUsage single process's memory usage. persent
	// if the return value is negative, check errno\getlasterror
	CybertronCoreAPI static int32_t procMemUsage(proc_stat_t* proc);
};


CYBERTRON_END
